#ifndef P2P_BASE_STUNSERVER_H_
#define P2P_BASE_STUNSERVER_H_

#include "base/asyncudpsocket.h"
#include "base/scoped_ptr.h"
#include "p2p/stun.h"

namespace cricket {

	const int STUN_SERVER_PORT = 3478;

	class StunServer : public sigslot::has_slots<> {
	public:
		// Creates a STUN server, which will listen on the given socket.
		explicit StunServer(base::AsyncUDPSocket* socket);
		// Removes the STUN server from the socket and deletes the socket.
		~StunServer();

	protected:
		// Slot for AsyncSocket.PacketRead:
		void OnPacket(
			base::AsyncPacketSocket* socket, const char* buf, size_t size,
			const base::SocketAddress& remote_addr);

		// Handlers for the different types of STUN/TURN requests:
		void OnBindingRequest(StunMessage* msg,
			const base::SocketAddress& addr);
		void OnAllocateRequest(StunMessage* msg,
			const base::SocketAddress& addr);
		void OnSharedSecretRequest(StunMessage* msg,
			const base::SocketAddress& addr);
		void OnSendRequest(StunMessage* msg,
			const base::SocketAddress& addr);

		// Sends an error response to the given message back to the user.
		void SendErrorResponse(
			const StunMessage& msg, const base::SocketAddress& addr,
			int error_code, const char* error_desc);

		// Sends the given message to the appropriate destination.
		void SendResponse(const StunMessage& msg,
			const base::SocketAddress& addr);

	private:
		base::scoped_ptr<base::AsyncUDPSocket> socket_;
	};

}  // namespace cricket

#endif  // P2P_BASE_STUNSERVER_H_
